﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
using Coding4Fun.Toolkit.Controls;
using ImageTools.IO.Bmp;
using ImageTools.IO.Gif;
using ImageTools.IO.Jpeg;
using ImageTools.IO.Png;
using Microsoft.Phone.Controls;
using Microsoft.Xna.Framework.GamerServices;

namespace TiebaSignWP7
{
    public partial class MainPage : PhoneApplicationPage
    {
        // 构造函数
        public MainPage()
        {
            InitializeComponent();
        }

        private CookieContainer cc = null;
        private string userName = "";
        private string password = "";
        private string verifyCode = "";
        private string imageUrl = "";
        private List<ListItem> displayList = new List<ListItem>();
        ScrollViewer v = new ScrollViewer();

        List<string> updateLs = new List<string>();
        List<string> tls = new List<string>();

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            cc = new CookieContainer();
            base.OnNavigatedTo(e);
            string un = "";
            string pw = "";
            if (NavigationContext.QueryString.TryGetValue("username", out un))
                userName = HttpUtility.UrlEncode(un);
            if (NavigationContext.QueryString.TryGetValue("password", out pw))
                password = HttpUtility.UrlEncode(pw);
        }

        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            //移除后退堆栈内的所有页面
            while (NavigationService.CanGoBack)
            {
                NavigationService.RemoveBackEntry();
            }
            v = VisualTreeHelper.GetChild(TiebaList, 0) as ScrollViewer;
            DoHttpWebRequestPOST("http://wappass.baidu.com/wp/login?uname_login=1");
        }

        #region 使用POST方式登录
        private void DoHttpWebRequestPOST(string paraUrl)
        {
            string url = paraUrl;
            //创建WebRequest类
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            if (cc == null)
                cc = new CookieContainer();
            request.CookieContainer = cc;
            request.Method = "POST";
            request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
            request.ContentType = "application/x-www-form-urlencoded";
            //返回异步操作的状态
            request.BeginGetRequestStream(new AsyncCallback(RequestStreamCallbackPOST), request);
        }

        private void RequestStreamCallbackPOST(IAsyncResult result)
        {
            HttpWebRequest request = (HttpWebRequest)result.AsyncState;
            Stream postStream = request.EndGetRequestStream(result);
            //POST提交服务器的资源
            string PostData = "username=" + userName + "&password=" + password
                + "&submit=%E7%99%BB%E5%BD%95&quick_user=0&isphone=0&sp_login=waprate&uname_login=&loginmerge=1&vcodestr=";
            Dispatcher.BeginInvoke(() =>
            {
                ToastPrompt tp = new ToastPrompt();
                try
                {
                    tp.Message = "正在登录";
                    tp.Show();
                }
                finally
                {
                    if (tp != null)
                        tp.Dispose();
                }
            });
            byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(PostData);
            postStream.Write(byteArray, 0, PostData.Length);
            postStream.Close();
            request.BeginGetResponse(new AsyncCallback(ResponseCallbackPOST), request);
        }

        private void ResponseCallbackPOST(IAsyncResult result)
        {
            string webPageContentString = "";
            try
            {
                //获取异步操作返回的的信息
                HttpWebRequest request = (HttpWebRequest)result.AsyncState;
                //结束对 Internet 资源的异步请求
                WebResponse response = request.EndGetResponse(result);
                //avoid multi-dispose by try finally segment
                Stream strm = null;
                try
                {
                    strm = response.GetResponseStream();
                    using (StreamReader sreader = new StreamReader(strm))
                    {
                        strm = null;
                        webPageContentString = sreader.ReadToEnd();
                        HandleLoginException(webPageContentString);
                    }
                }
                finally
                {
                    if (strm != null)
                        strm.Dispose();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
        #endregion

        #region 使用POST方式登录WithVerfyCode
        private void DoHttpWebRequestPOSTWithVerifyCode(string paraUrl)
        {
            string url = paraUrl;
            //创建WebRequest类
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            if (cc == null)
                cc = new CookieContainer();
            request.CookieContainer = cc;
            request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36";
            request.Method = "POST";
            request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
            request.ContentType = "application/x-www-form-urlencoded";
            //返回异步操作的状态
            request.BeginGetRequestStream(new AsyncCallback(RequestStreamCallbackPOSTWithVerifyCode), request);
        }

        private void RequestStreamCallbackPOSTWithVerifyCode(IAsyncResult result)
        {
            HttpWebRequest request = (HttpWebRequest)result.AsyncState;
            Stream postStream = request.EndGetRequestStream(result);
            //POST提交服务器的资源
            string PostData = "username=" + userName + "&password=" + password + "&verifycode=" + verifyCode
                + "&submit=%E7%99%BB%E5%BD%95&quick_user=0&isphone=0&sp_login=waprate&uname_login=&loginmerge=1&vcodestr="
                + imageUrl.Substring(imageUrl.IndexOf('?') + 1);
            Dispatcher.BeginInvoke(() =>
            {
                ToastPrompt tp = new ToastPrompt();
                try
                {
                    tp.Message = "正在登录";
                    tp.Show();
                }
                finally
                {
                    if (tp != null)
                        tp.Dispose();
                }
            });
            byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(PostData);
            postStream.Write(byteArray, 0, PostData.Length);
            postStream.Close();
            request.BeginGetResponse(new AsyncCallback(ResponseCallbackPOSTWithVerifyCode), request);
        }

        private void ResponseCallbackPOSTWithVerifyCode(IAsyncResult result)
        {
            string webPageContentString = "";
            try
            {
                //获取异步操作返回的的信息
                HttpWebRequest request = (HttpWebRequest)result.AsyncState;
                //结束对 Internet 资源的异步请求
                WebResponse response = request.EndGetResponse(result);
                //avoid multi-dispose by try finally segment
                Stream strm = null;
                try
                {
                    strm = response.GetResponseStream();
                    using (StreamReader sreader = new StreamReader(strm))
                    {
                        strm = null;
                        webPageContentString = sreader.ReadToEnd();
                        HandleLoginException(webPageContentString);
                    }
                }
                finally
                {
                    if (strm != null)
                        strm.Dispose();
                }
            }
            catch (Exception ex)
            {
                Dispatcher.BeginInvoke(() =>
                {
                    MessageBox.Show(ex.ToString());
                });
            }
        }
        #endregion

        #region 获取并输入验证码
        private void FindVerifyCodeImageUrl(string s)
        {
            string rs = "(请您输入验证码)(.*?)(验证码：<img src=\")(.*?)(\" alt=\"wait...\")";
            Regex r = new Regex(rs, RegexOptions.IgnoreCase | RegexOptions.Singleline);
            Match m = r.Match(s);
            for (; m.Success; m = m.NextMatch())
            {
                imageUrl = m.Groups[4].ToString();
            }
            ShowVerifyCodeInput(imageUrl);
        }

        private void ShowVerifyCodeInput(string imgUrl)
        {
            Dispatcher.BeginInvoke(() =>
            {
                VerifyCodeStack.Visibility = Visibility.Visible;
                ImageTools.IO.Decoders.AddDecoder<GifDecoder>();
                ImageTools.IO.Decoders.AddDecoder<BmpDecoder>();
                ImageTools.IO.Decoders.AddDecoder<JpegDecoder>();
                ImageTools.IO.Decoders.AddDecoder<PngDecoder>();
                ImageTools.ExtendedImage img = new ImageTools.ExtendedImage();
                img.UriSource = new Uri(imgUrl, UriKind.RelativeOrAbsolute);
                VerifyCodeImage.Source = img;
            });
        }

        private void VerifyCodeConfirmButtom_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            verifyCode = VerifyCode.Text;
            DoHttpWebRequestPOSTWithVerifyCode("http://wappass.baidu.com/passport/login");
            Dispatcher.BeginInvoke(() =>
            {
                VerifyCodeStack.Visibility = Visibility.Collapsed;
            });
        }
        #endregion

        private void HandleLoginException(string webPageContentString)
        {
            if (webPageContentString.Contains("下次再绑定"))
            {
                Dispatcher.BeginInvoke(() =>
                {
                    ToastPrompt tp = new ToastPrompt();
                    try
                    {
                        tp.Message = "百度网站提示需要绑定手机或邮箱才能继续，请自行绑定后重试！";
                        tp.TextWrapping = TextWrapping.Wrap;
                        tp.Show();
                    }
                    finally
                    {
                        if (tp != null)
                            tp.Dispose();
                    }
                });
            }
            else if (webPageContentString.Contains("请您输入验证码"))
            {
                Dispatcher.BeginInvoke(() =>
                {
                    ToastPrompt tp = new ToastPrompt();
                    try
                    {
                        tp.Message = "这次登录需要验证码哦！";
                        tp.Show();
                    }
                    finally
                    {
                        if (tp != null)
                            tp.Dispose();
                    }
                });
                FindVerifyCodeImageUrl(webPageContentString);
            }
            else if (webPageContentString.Contains("您输入的验证码有误"))
            {
                Dispatcher.BeginInvoke(() =>
                {
                    ToastPrompt tp = new ToastPrompt();
                    try
                    {
                        tp.Message = "验证码输错了，返回重试一下吧！";
                        tp.Show();
                    }
                    finally
                    {
                        if (tp != null)
                            tp.Dispose();
                    }
                });
            }
            else if (webPageContentString.Contains("您输入的密码有误"))
            {
                Dispatcher.BeginInvoke(() =>
                {
                    ToastPrompt tp = new ToastPrompt();
                    try
                    {
                        tp.Message = "登录失败，请返回检查一下用户名和密码！";
                        tp.Show();
                    }
                    finally
                    {
                        if (tp != null)
                            tp.Dispose();
                    }
                });
            }
            else
            {
                Dispatcher.BeginInvoke(() =>
                {
                    ToastPrompt tp = new ToastPrompt();
                    try
                    {
                        tp.Message = "登录成功";
                        tp.Show();
                    }
                    finally
                    {
                        if (tp != null)
                            tp.Dispose();
                    }
                });
                GotoSign(cc);
            }
        }

        private void GotoSign(CookieContainer cc)
        {
            TiebaListGetter tlg = new TiebaListGetter(cc);
            TBSGetter tbsg = new TBSGetter(cc);
            SignWAPFormatGetter swfg = new SignWAPFormatGetter(cc);

            Dispatcher.BeginInvoke(() =>
            {
                ToastPrompt tp = new ToastPrompt();
                try
                {
                    tp.Message = "正在获取列表";
                    tp.Show();
                }
                finally
                {
                    if (tp != null)
                        tp.Dispose();
                }
            });
            tls = tlg.GetDetailListFromBlockList(tlg.GetBlockList());
            foreach (string s in tls)
            {
                updateLs.Add("请稍候... ");
            }
            Dispatcher.BeginInvoke(() => { BindListBox(tls, updateLs); });
            //开始签到
            string tbsgString = tbsg.GetTBS();
            string swfgString = swfg.GetSignWAPFormat();
            WAPSigner waps = new WAPSigner(cc, tls, tbsgString, swfgString);
            //
            waps.wsd = new WAPSigner.WAPSignerDelegate(BindListBox);
            waps.wsscd = new WAPSigner.WAPSignerSCompleteDelegate(ShowSignComplete);
            Dispatcher.BeginInvoke(() =>
            {
                ToastPrompt tp = new ToastPrompt();
                try
                {
                    tp.Message = "正在签到";
                    tp.Show();
                }
                finally
                {
                    if (tp != null)
                        tp.Dispose();
                }
                Guide.IsScreenSaverEnabled = false;
            });
            waps.Sign();
        }

        private void BindListBox(List<string> tls, List<string> updateLs)
        {
            this.Dispatcher.BeginInvoke((Action)delegate()
            {
                displayList.Clear();
                for (int i = 0; i < updateLs.Count; i++)
                {
                    displayList.Add(new ListItem
                    {
                        num = (i + 1).ToString(),
                        name = tls[i].Split(',')[0],
                        value = tls[i].Split(',')[1],
                        grade = tls[i].Split(',')[2] + tls[i].Split(',')[3],
                        updateInfo = updateLs[i]
                    });
                }
                Dispatcher.BeginInvoke(() =>
                {
                    TiebaList.ItemsSource = null;
                    TiebaList.ItemsSource = displayList;
                    TiebaList.SelectedItem = TiebaList.Items[TiebaList.Items.Count - 1];
                    v.ScrollToVerticalOffset(TiebaList.SelectedIndex);
                });
            });
        }

        private void ShowSignComplete(bool flag)
        {
            this.Dispatcher.BeginInvoke((Action)delegate()
            {
                if (flag == true)
                {
                    Dispatcher.BeginInvoke(() =>
                    {
                        ToastPrompt tp = new ToastPrompt();
                        try
                        {
                            tp.Message = "签到完成";
                            tp.Show();
                        }
                        finally
                        {
                            if (tp != null)
                                tp.Dispose();
                        }
                        Guide.IsScreenSaverEnabled = true;
                    });
                }
            });
        }
    }
}